/**
* netclient factory
* @author thinkry
*/

#ifndef __MPSVR_NETCLIENTFACTORY_H__
#define __MPSVR_NETCLIENTFACTORY_H__

#include <CTBase.h>
#include <CTObjectMgr.h>
#include "mpnetclient.h"

class CMpNetClientFactory
{
protected:
    enum
    {
        LIST_COUNT = 4,
        INDEX_COUNT = 2,

        ALLOC_INDEX = 0,
        FREE_LIST = 0,
        USED_LIST = 1,

        STATUS_INDEX = 1,
        // 0还是FREE_LIST
        IDLE_LIST = 1,
        BUSY_LIST = 2,
        CLOSING_LIST = 3,
    };

    CTLib::CTObjectMgr<CMpNetClient>       m_stMgr;

public:
    CMpNetClientFactory();
    virtual ~CMpNetClientFactory();

    int Init(const char* pszBuffer, int iBufferSize, int iObjectCount);

    static size_t CountSize(int iObjectCount)
    {
        return CTObjectMgr<CMpNetClient>::CountSize(iObjectCount,
            sizeof(CMpNetClient), LIST_COUNT, INDEX_COUNT);
    }

    /**
    * pstClient在数组中的下标
    */
    int CalcObjectPos(const CMpNetClient* pstClient) const
    {
        int i = (char*)pstClient - (char*)&m_stMgr[0];
        CT_ASSERT(i >= 0 && (i % sizeof(CMpNetClient) == 0));

        return i / sizeof(CMpNetClient);
    }

    /** 返回在用的Client的数量, 包括空闲的和在忙的 */
    int GetUsedClientCount() const
    {
        return m_stMgr.ListInfo(USED_LIST, ALLOC_INDEX).iSize;
    }

    //获取空闲client数量
    int GetIdleClientCount() const 
    {
        return m_stMgr.ListInfo(IDLE_LIST, STATUS_INDEX).iSize;
    }

    CMpNetClient* New();
    int Delete(CMpNetClient* pstClient);
    CMpNetClient* AllocOneIdle();

    int SetIdle(CMpNetClient* pstClient);
    int SetBusy(CMpNetClient* pstClient);
    int SetClosing(CMpNetClient* pstClient);

    int GetStatus(CMpNetClient* pstClient)
    {
        int i = CalcObjectPos(pstClient);
        return m_stMgr.Flag(i, STATUS_INDEX);
    }

    bool IsIdle(CMpNetClient* pstClient)
    {
        return GetStatus(pstClient) == IDLE_LIST;
    }

    bool IsClosing(CMpNetClient* pstClient)
    {
        return GetStatus(pstClient) == CLOSING_LIST;
    }
};

#endif //__MPSVR_NETCLIENTFACTORY_H__
